package ict.kth.se.web;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ict.kth.se.manager.CookieManager;
import ict.kth.se.manager.SeekerManager;
import ict.kth.se.model.Availability;
import ict.kth.se.model.Competence;
import ict.kth.se.model.CompetenceProfile;
import ict.kth.se.model.Person;
import ict.kth.se.model.Role;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class SeekerController {

	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	private SeekerManager seekerManager;
	
	/**
	 * public constructor
	 * @param seekerManager seekermanager to be set
	 */
	@Autowired
	public SeekerController(SeekerManager seekerManager) {
		this.seekerManager = seekerManager;
	}
	
	/**
	 * method createNewSeeker() creates a seeker
	 * @param firstName person firstname
	 * @param lastName person lastname
	 * @param email person email
	 * @param language chosen language
	 * @param request HTTPServletRequest
	 * @param response HTTPServletResponse
	 * @return modelandview
	 * @throws Exception if something went wrong
	 */
	@RequestMapping("createNewSeeker")
	public ModelAndView createNewSeeker(@RequestParam("firstName") String firstName, @RequestParam("lastName") String lastName,  
			@RequestParam("email") String email, @RequestParam(value="language", required=false) String language,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView	=	new ModelAndView("newSeekerForm");
		for(Competence competence : seekerManager.getAllCompetences()){
			//System.out.println("ONE: "+competence.getNameSe());
		}
		modelAndView.addObject("allCompetences", seekerManager.getAllCompetences());
		modelAndView	=	CookieManager.handleLanguageCookie(modelAndView, request, response, language);
		Person person 	= 	new Person(firstName, lastName, email);
		
		modelAndView.addObject("person", person);
		return modelAndView;
	}
	
	/**
	 * This method unpacks parameters from view and sends them to SeekerManager to create a new Seeker in a DB
	 * @param firstName person firstname
	 * @param lastName person lastname
	 * @param email person email
	 * @param language chosen language
	 * @param request httpservletrequest
	 * @param response httpservletresponse
	 * @return modelandview
	 * @throws Exception if something went wrong
	 */
	@RequestMapping("insertNewSeeker")
	public ModelAndView insertNewSeeker(
			@RequestParam("firstName") String firstName, 
			@RequestParam("lastName") String lastName,  
			@RequestParam("email") String email, 
			@RequestParam("ssn") String ssn,
			@RequestParam("allCompetencesInput") String allCompetencesString,
			@RequestParam("allAvailabillitiesInput") String allAvailabilitiesString,
			@RequestParam(value="language", required=false) String language,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		try{
			//Create modelAndView to be sent to view
			ModelAndView modelAndView = new ModelAndView("seekerDetails");
			//Language
			modelAndView = CookieManager.handleLanguageCookie(modelAndView, request, response, language);
			
			//Validation
			if(firstName.equals("") || lastName.equals("") || email.equals("") || ssn.equals("")){
				throw new Exception("Some of mandatory params was empty");
			}
			else{
				//Validate ssn
				String[] parts = ssn.split("-");
				if(parts.length != 2)
					throw new Exception("Corrupted ssn.");
				else{
					try{
						Integer.parseInt(parts[0]);
						Integer.parseInt(parts[1]);
					}
					catch(Exception e){
						throw new Exception("Corrupted ssn.");
					}
				}
				//Validate email
				parts = email.split("@");
				if(parts.length != 2)
					throw new Exception("Corrupted email.");
				else{
					if(parts[1].indexOf('.') == -1)
						throw new Exception("Corrupted email.");
				}
			}
		
			//Gets params and maps them into objects
			Person person = new Person(firstName, lastName, email);
			person.setSsn(ssn);
		
			//Add USER role to person
			Role role = new Role();
			role.setName(Role.ROLE_USER);
			person.setRole(role);
		
			//Unpacks strings for availability and competence into Availability and CompetenceProfiles and Competences
			//There's semicolon on the end which has to be removes
			try{
				allCompetencesString.substring(0, allCompetencesString.lastIndexOf(";"));
				String[] competencesStrings = allCompetencesString.split(";");
				if(competencesStrings.length == 0){
					throw new Exception();
				}
				List<CompetenceProfile> competenceProfiles = new ArrayList<CompetenceProfile>();
				for(int i=0; i<competencesStrings.length; i++){
					Competence competence = new Competence();
					String[] oneCompetence = competencesStrings[i].split(":");
					competence.setId(Long.parseLong(oneCompetence[0]));
					CompetenceProfile competenceProfile = new CompetenceProfile();
					competenceProfile.setCompetence(competence);
					competenceProfile.setYearsOfExperience(Float.parseFloat(oneCompetence[1]));
					competenceProfiles.add(competenceProfile);
				}
				person.setCompetenceProfiles(competenceProfiles);
			}
			catch(Exception e){
				e.printStackTrace();
				throw new Exception("You have an error in all competences.");
			}
			
			try{
				//There's semicolon on the end which has to be removes
				allAvailabilitiesString.substring(0, allAvailabilitiesString.lastIndexOf(";"));
				String[] availabilitiesStrings = allAvailabilitiesString.split(";");
				if(availabilitiesStrings.length == 0){
					throw new Exception();
				}
				List<Availability> availabilities = new ArrayList<Availability>();
				for(int i=0; i<availabilitiesStrings.length; i++){
					Availability availability = new Availability();
					String[] oneAvailability = availabilitiesStrings[i].split(":");
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
					Date start = sdf.parse(oneAvailability[0]);
					Calendar startCal = Calendar.getInstance();
					startCal.setTime(start);
					startCal.add(Calendar.MONTH, 1);
					Date end = sdf.parse(oneAvailability[1]);
					Calendar endCal = Calendar.getInstance();
					endCal.setTime(end);
					endCal.add(Calendar.MONTH, 1);
					availability.setFromDate(startCal);
					availability.setToDate(endCal);
					availabilities.add(availability);
				}
				person.setAvailabilities(availabilities);
			}
			catch(Exception e){
				throw new Exception("You have an error in all availabilities.");
			}
			
			person = seekerManager.createNewPerson(person);
			
			modelAndView.addObject("person", person);
			
			return modelAndView;
		}
		catch(Exception e){
			e.printStackTrace();
			//Create modelAndView to be sent to view for errors
			ModelAndView modelAndView = new ModelAndView("error");
			modelAndView.addObject("error", e.getMessage());
			return modelAndView;
		}
	}
}
